package com.breeze.blockchain.service.strategy.login;

import static com.breeze.blockchain.common.exception.BizErrorCode.LOGIN_ERROR;
import static com.breeze.blockchain.common.exception.BizErrorCode.UNDEFINED_LOGIN_TYPE;

import com.breeze.blockchain.auth.util.AppUserUtil;
import com.breeze.blockchain.common.enums.LoginTypeEnum;
import com.breeze.blockchain.mybatis.entity.UserDo;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 登陆策略上下文
 *
 * @author breeze
 */
@Service
public final class LoginStrategyContext {

  private final ConcurrentHashMap<LoginTypeEnum, LoginStrategy> strategyMap =
      new ConcurrentHashMap<>();

  @Autowired
  public LoginStrategyContext(List<LoginStrategy> strategies) {
    strategies.forEach(strategy -> strategyMap.put(strategy.loginType(), strategy));
  }

  public UserDo login(
      LoginTypeEnum loginType, String mobile, String email, String password, String code) {
    var strategy = getStrategy(loginType);
    UserDo loginUser =
        switch (loginType) {
          case PASSWORD -> strategy.login(mobile, password);
          case MOBILE_CODE -> strategy.login(mobile, code);
          case EMAIL -> strategy.login(email, code);
        };
    LOGIN_ERROR.notNull(loginUser);
    AppUserUtil.login(loginUser.getId());
    loginUser.setAccessToken(AppUserUtil.getTokenValue());
    return loginUser;
  }

  private LoginStrategy getStrategy(LoginTypeEnum strategyType) {
    var strategy = this.strategyMap.get(strategyType);
    UNDEFINED_LOGIN_TYPE.notNull(strategy, strategyType.getCode());
    return strategy;
  }
}
